package com.fhc.amap

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.Window
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.*
import com.amap.api.maps.model.animation.AlphaAnimation
import com.amap.api.maps.model.animation.Animation
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.core.PoiItem
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import com.amap.api.services.help.Tip
import com.amap.api.services.poisearch.PoiResult
import com.amap.api.services.poisearch.PoiSearch
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.fhc.amap.model.PositionItem
import com.gyf.barlibrary.ImmersionBar
import kotlinx.android.synthetic.main.activity_location_amap.*

class AMapActivity : AppCompatActivity(), GeocodeSearch.OnGeocodeSearchListener {
    private val tag = AMapActivity::class.java.canonicalName

    companion object {
        const val SEARCH_REQUEST_CODE = 1001
        const val POSITION_REQUEST_CODE = 1002
        const val SELECT_POSITION = "SELECT_POSITION"
        const val SURE_POSITION = "SURE_POSITION"
    }

    //地图交互核心方法
    private lateinit var aMap: AMap
    //地图中心点
    private lateinit var centerMaker: Marker
    //定位适配器
    private lateinit var adapter: LocationAdapter
    //定位列表数据
    private var mLocationList: MutableList<PositionItem> = ArrayList()
    //判断是来自地图还是列表的点击
    private var isTouch = false //false 不进行附件搜索
    private var centerLocation: LatLng? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 无标题
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
        setContentView(R.layout.activity_location_amap)
        //着色状态栏
        setStatusBar()
        initViewAndData(savedInstanceState)
    }

    private fun setStatusBar() {
        ImmersionBar.with(this).statusBarColor(R.color.white).fitsSystemWindows(true).statusBarDarkFont(true, 0.2f)
                .init()
    }

    //初始化界面数据
    private fun initViewAndData(savedInstanceState: Bundle?) {
        map_view.onCreate(savedInstanceState)
        aMap = map_view.map
        //地图初始化
        initMap(aMap)
        //列表初始化
        rlv_location_list.layoutManager = LinearLayoutManager(this)
        adapter = LocationAdapter(mLocationList)
        adapter.isUseEmpty(false)
        rlv_location_list.adapter = adapter
        //列表点击事件
        adapter.onItemClickListener = BaseQuickAdapter.OnItemClickListener { _, _, position ->
            if (mLocationList.isEmpty()) return@OnItemClickListener
            isTouch = false
            //地图移动
            val point = mLocationList[position].latLonPoint
            point?.let{
                val latLng = LatLng(point.latitude, point.longitude)
                aMap.animateCamera(CameraUpdateFactory.changeLatLng(latLng))
            }

            //更改列表的选中
            mLocationList.forEach {
                it.isSelect = false
            }
            mLocationList[position].isSelect = true
            adapter.notifyDataSetChanged()
        }
        //设置地图拖动监听
        aMap.setOnMapTouchListener {
            isTouch = true
            centerLocation = null
        }
        aMap.setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
            override fun onCameraChangeFinish(cameraPosition: CameraPosition) {
                if (isTouch) {
                    val latLng = cameraPosition.target
                    Log.d(tag, "位置信息：${latLng.latitude}//${latLng.longitude}")
                    //查找附近数据
                    aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18f))
                    val geocoderSearch = GeocodeSearch(this@AMapActivity)
                    geocoderSearch.setOnGeocodeSearchListener(this@AMapActivity)
                    val query = RegeocodeQuery(LatLonPoint(latLng.latitude, latLng.longitude), 200f, GeocodeSearch.AMAP)
                    centerLocation = latLng
                    geocoderSearch.getFromLocationAsyn(query)
                    //searchNearby(latLng)
                }
            }

            override fun onCameraChange(p0: CameraPosition?) {
            }

        })
        //定位按钮的点击事件
        location_location.setOnClickListener {
            //获取当前位置
            getCurrentLocation { locationSuccess(it) }
        }
        //搜索按钮点击事件
        iv_position_search.setOnClickListener {
            val intent = Intent(this, AMapSearchActivity::class.java)
            startActivityForResult(intent, SEARCH_REQUEST_CODE)
        }
        //返回键
        iv_title_back.setOnClickListener { finish() }
        //获取当前位置
        getCurrentLocation { locationSuccess(it) }
        //发送当前位置
        tv_send_position.setOnClickListener {
            if (mLocationList.isNotEmpty()) {
                val positionItem = mLocationList.filter { it.isSelect }[0]
                positionItem.let {
                    val data = Intent()
                    data.putExtra(SURE_POSITION, positionItem)
                    setResult(Activity.RESULT_OK, data)
                }
            }
            finish()
        }
    }

    //接收返回的数据
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == SEARCH_REQUEST_CODE && resultCode == RESULT_OK) {
            val resultTip = data!!.getParcelableExtra<Tip>(SELECT_POSITION)
            //清空列表数据
            mLocationList.clear()
            adapter.setNewData(mLocationList)
            isTouch = false
            resultTip?.point?.let {
                val latLng = LatLng(resultTip.point.latitude, resultTip.point.longitude)
                //地图移动
                aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18f))
                //构造列表的第一个定位数据
                val poiItem = PositionItem("", LatLonPoint(resultTip.point.latitude, resultTip.point.longitude), resultTip.name, if (resultTip.address.isEmpty()) resultTip.district else resultTip.address )
                poiItem.isSelect = true
                poiItem.isMyLocation = true
                mLocationList.add(poiItem)
                //查找附近的数据
                searchNearby(latLng)
            }
        }
    }

    //获取当前位置
    private fun getCurrentLocation(success: (AMapLocation) -> Unit) {
        isTouch = false
        val mLocationClient = AMapLocationClient(this)
        val mLocationOption = AMapLocationClientOption()
        //高精度模式
        mLocationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
        //定位请求超时时间
        mLocationOption.httpTimeOut = 50000
        // 关闭缓存机制
        mLocationOption.isLocationCacheEnable = false
        // 设置是否只定位一次
        mLocationOption.isOnceLocation = true
        //设置参数
        mLocationClient.setLocationOption(mLocationOption)
        // 启动定位
        mLocationClient.startLocation()
        //定位监听
        mLocationClient.setLocationListener { aMapLocation ->
            //定位成功之后取消定位
            mLocationClient.stopLocation()
            if (aMapLocation != null && aMapLocation.errorCode == 0) {
                Log.d(tag, "定位成功: " + aMapLocation.toStr())
                success(aMapLocation)
            } else {
                Log.d(tag, "定位失败，请重新定位")
            }
        }
    }

    //定位列表适配器
    class LocationAdapter(data: List<PositionItem>) :
        BaseQuickAdapter<PositionItem, BaseViewHolder>(R.layout.item_location, data) {
        override fun convert(helper: BaseViewHolder, item: PositionItem) {
            helper.apply {
                setText(R.id.tv_location_name, item.poiName)
                setText(R.id.tv_location_name_dec, if (item.isMyLocation) item.address else item.provinceName + item.cityName + item.address)
                setGone(R.id.iv_position_select, item.isSelect)
            }
        }
    }

    //定位成功之后，构造Marker对象和数据
    private fun locationSuccess(location: AMapLocation) {
        aMap.clear()
        pb_location.visibility = View.VISIBLE
        rlv_location_list.visibility = View.INVISIBLE
        //清空列表数据
        mLocationList.clear()
        adapter.setNewData(mLocationList)
        val latLng = LatLng(location.latitude, location.longitude)
        //定位蓝点
        val marker = aMap.addMarker(
            MarkerOptions().position(latLng).title("").snippet("").icon(
                BitmapDescriptorFactory.fromResource(R.mipmap.ic_location_point)))
        //蓝点动画
        val alpha = AlphaAnimation(1f, 0.5f)//新建透明度动画
        alpha.setDuration(1000)//设置动画持续时间
        alpha.repeatCount = -1
        alpha.repeatMode = Animation.REVERSE
        marker.setAnimation(alpha)//图片设置动画
        marker.startAnimation()//开始动画
        //定位针
        centerMaker = aMap.addMarker(MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.mipmap.my_location)).position(latLng).draggable(true).title("").snippet(""))
        //定位针一直在中心
        centerMaker.setPositionByPixels(map_view.width / 2, map_view.height / 2)
        //移动地图
        aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18f))
        //构造列表的第一个定位数据
        val poiItem =
            PositionItem("当前位置", LatLonPoint(location.latitude, location.longitude), location.poiName, location.address)
        poiItem.provinceName = location.province
        poiItem.cityName = location.city
        poiItem.adName = location.adCode
        poiItem.cityCode = location.cityCode
        poiItem.isSelect = true
        poiItem.isMyLocation = true
        mLocationList.add(poiItem)
        //查找附近的数据
        searchNearby(latLng)
    }

    //查找附近的数据
    private fun searchNearby(latLng: LatLng) {
        pb_location.visibility = View.VISIBLE
        rlv_location_list.visibility = View.INVISIBLE
        //keyWord表示搜索字符串，
        //第二个参数表示POI搜索类型，二者选填其一，选用POI搜索类型时建议填写类型代码，码表可以参考下方（而非文字）
        //cityCode表示POI搜索区域，可以是城市编码也可以是城市名称，也可以传空字符串，空字符串代表全国在全国范围内进行搜索
        val query = PoiSearch.Query("", "", "")
        query.pageSize = 10// 设置每页最多返回多少条poiitem
        val search = PoiSearch(this, query)
        //设置周边搜索的中心点以及半径
        search.bound = PoiSearch.SearchBound(LatLonPoint(latLng.latitude, latLng.longitude), 10000)
        search.setOnPoiSearchListener(object : PoiSearch.OnPoiSearchListener {
            override fun onPoiItemSearched(p0: PoiItem?, p1: Int) { }

            override fun onPoiSearched(result: PoiResult?, code: Int) {
                //1000为成功，其他为失败
                if (code == 1000) {
                    val pois = result?.pois
                    //重新构造数据
                    pois?.forEach {
                        mLocationList.add(PositionItem(it.poiId, it.latLonPoint, it.title, it.snippet, it.provinceName, it.cityName, it.adName, it.cityCode))
                    }
                    //如果有当前定位的数据的话，就直接选中，否则用返回的数据的第一条，选中
                    if (mLocationList.isEmpty() || !mLocationList[0].isMyLocation) {
                        mLocationList[0].isSelect = true
                    }
                    adapter.isUseEmpty(mLocationList.isEmpty())
                    //设置数据
                    adapter.setNewData(mLocationList)
                } else {
                    adapter.isUseEmpty(true)
                }
                pb_location.visibility = View.GONE
                rlv_location_list.visibility = View.VISIBLE
            }
        })
        //发送请求
        search.searchPOIAsyn()
    }

    //初始化地图参数
    private fun initMap(aMap: AMap) {
        //设置地图是否显示放大
        aMap.uiSettings.isZoomControlsEnabled = false
        // 设置地图默认的指南针是否显示
        aMap.uiSettings.isCompassEnabled = false
        // 设置默认定位按钮是否显示
        aMap.uiSettings.isMyLocationButtonEnabled = false
        //隐藏logo
        aMap.uiSettings.setLogoBottomMargin(-80)
        // 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        aMap.isMyLocationEnabled = false
    }

    override fun onDestroy() {
        super.onDestroy()
        ImmersionBar.with(this).destroy()
        map_view.onDestroy()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        map_view.onSaveInstanceState(outState)
    }

    override fun onRegeocodeSearched(p0: RegeocodeResult?, p1: Int) {
        p0?.let {
            //构造列表的第一个定位数据
            centerLocation?.let {
                mLocationList.clear()
                adapter.setNewData(mLocationList)
                val formatAddress = p0.regeocodeAddress.formatAddress
                val province = p0.regeocodeAddress.province
                val city = p0.regeocodeAddress.city
                val district = p0.regeocodeAddress.district
                val address = formatAddress.replace(province, "")
                        .replace(city, "")
                        .replace(district, "")
                val poiItem = PositionItem("", LatLonPoint(centerLocation!!.latitude, centerLocation!!.longitude),
                        address, formatAddress, p0.regeocodeAddress.province,
                        p0.regeocodeAddress.city, "",p0.regeocodeAddress.cityCode)
                poiItem.isSelect = true
                poiItem.isMyLocation = true
                mLocationList.add(poiItem)
                searchNearby(centerLocation!!)
            }
        }
    }

    override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {

    }
}